package com.rtx.config.exception;

import java.io.IOException;

import org.apache.shiro.ShiroException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import com.rtx.exception.RtxWmsException;
import com.rtx.model.dto.response.ResponseModel;
import com.rtx.model.emums.ExceptionCodeEnum;

import cn.hutool.core.util.StrUtil;

/**
 * 针对单个指定异常捕获，并且定义错误的返回体
 *
 * @author Zy
 */
@RestControllerAdvice
public class ExceptionConfig {
	
	Logger log = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private LanguageConfig languageConfig;

    /**
     * 捕捉shiro的异常
     *
     * @param e
     * @return
     */
    @ResponseBody
    @ExceptionHandler(ShiroException.class)
    public ResponseModel handleShiRoException(ShiroException e) {

        e.printStackTrace();
        log.info("ShiroException异常信息：{}", e.getMessage());
        return ResponseModel.fail(e.getMessage());
    }

    /**
     * Http消息不可读异常
     *
     * @param e
     * @return
     */
    @ResponseBody
    @ExceptionHandler(HttpMessageNotReadableException.class)
    public ResponseModel handleParamJsonException(HttpMessageNotReadableException e) {

        e.printStackTrace();
        log.info("HttpMessageNotReadableException异常信息：{}", e.getMessage());
        return ResponseModel.fail(e.getMessage());
    }

    /**
     * 全局业务异常处理
     *
     * @param e
     * @return
     */
    @ResponseBody
    @ExceptionHandler(RtxWmsException.class)
    public ResponseModel APIGlobalExceptionHandler(RtxWmsException e) {

        e.printStackTrace();
        String message = languageConfig.getLocaleMessage(e.getCode(), e.getParams());
        if (!StrUtil.isBlank(e.getReturnCode())) {
            return ResponseModel.fail(e.getReturnCode(), message);
        }
        log.info("RtxWmsException异常信息：{}", e.getMessage());
        return ResponseModel.fail(message);
    }

    /**
     * 全局实体属性验证异常处理
     *
     * @param e
     * @return
     */
    @ResponseBody
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseModel MethodArgumentNotValidGlobalExceptionHandler(MethodArgumentNotValidException e) {

        e.printStackTrace();
        log.info("MethodArgumentNotValidException异常信息：{}", e.getMessage());
        return ResponseModel.fail(e.getMessage());
    }

    /**
     * 空指针异常处理
     *
     * @param e
     * @return
     */
    @ResponseBody
    @ExceptionHandler(NullPointerException.class)
    public ResponseModel NullPointerGlobalExceptionHandler(NullPointerException e) {

        e.printStackTrace();
        log.info("NullPointerException异常信息：{}", e.getMessage());
        StackTraceElement stackTraceElement = e.getStackTrace()[0];
        return ResponseModel.fail("具体文件. " + stackTraceElement.getClassName() + ". 所属行号. " + stackTraceElement.getLineNumber());
    }

    /**
     * jackson取值异常处理
     *
     * @param e
     * @return
     */
    @ResponseBody
    @ExceptionHandler(IOException.class)
    public ResponseModel IOEGlobalExceptionHandler(IOException e) {

        e.printStackTrace();
        log.info("IOException异常信息：{}", e.getMessage());
        StackTraceElement stackTraceElement = e.getStackTrace()[0];
        return ResponseModel.fail("具体文件. " + stackTraceElement.getClassName() + ". 所属行号. " + stackTraceElement.getLineNumber());
    }

    /**
     * 索引越界异常处理
     *
     * @param e
     * @return
     */
    @ResponseBody
    @ExceptionHandler(IndexOutOfBoundsException.class)
    public ResponseModel IndexOutOfBoundsGlobalExceptionHandler(IndexOutOfBoundsException e) {

        e.printStackTrace();
        log.info("IndexOutOfBoundsException异常信息：{}", e.getMessage());
        StackTraceElement stackTraceElement = e.getStackTrace()[3];
        return ResponseModel.fail("具体文件. " + stackTraceElement.getClassName() + ". 所属行号. " + stackTraceElement.getLineNumber(), ResponseModel.FAILED_CODE);
    }

    /**
     * 全局异常捕捉处理
     *
     * @param e
     * @return
     */
    @ResponseBody
    @ExceptionHandler(Exception.class)
    public ResponseModel errorHandler(Exception e) {

        e.printStackTrace();
        log.info("Exception异常信息：{}", e.getMessage());
        String message = languageConfig.getLocaleMessage(ExceptionCodeEnum.EXC_000000.getCode(), e.getMessage());
        return ResponseModel.fail(message);
    }
}
